package com.niiwoo.civet.account.service.dubbo;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.account.dao.entity.*;
import com.niiwoo.civet.account.dto.common.LanMaoGatewayRequestDTO;
import com.niiwoo.civet.account.dto.request.*;
import com.niiwoo.civet.account.dto.response.*;
import com.niiwoo.civet.account.enums.*;
import com.niiwoo.civet.account.service.AccountRegisterDubboService;
import com.niiwoo.civet.account.service.local.AccountRegisterLocalService;
import com.niiwoo.civet.account.service.local.openAccount2.dto.*;
import com.niiwoo.civet.account.service.local.openAccount2.lanmao.LanMaoHelper;
import com.niiwoo.civet.account.service.local.openAccount2.service.OpenAccountServices;
import com.niiwoo.civet.user.service.UserAuthorizationInfoDubboService;
import com.niiwoo.tripod.lanmao.component.LanMaoGatewayService;
import com.niiwoo.tripod.lanmao.component.LanMaoSequence;
import com.niiwoo.tripod.lanmao.enums.*;
import com.niiwoo.tripod.lanmao.request.CompanyBindBankCardExpandRequest;
import com.niiwoo.tripod.lanmao.request.CompanyBindBankCardRegisterRequest;
import com.niiwoo.tripod.lanmao.response.LanMaoGatewayDTO;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;

/**
 * 个人开户API实现
 */
@Service(version = "1.0.0")
@Slf4j
public class AccountRegisterDubboServiceImpl implements AccountRegisterDubboService {
    @Autowired
    OpenAccountServices openAccountServices;
    @Autowired
    LanMaoGatewayService lanMaoGatewayService;
    @Autowired
    LanMaoSequence lanMaoSequence;
    @Autowired
    AccountRegisterLocalService accountRegisterLocalService;
    @Autowired
    SnowflakeIdWorker snowflakeIdWorker;
    @Reference(version = "1.0.0")
    private UserAuthorizationInfoDubboService userAuthorizationInfoDubboService;

    /**
     * 校验开户状态
     */
    @Override
    public AccountRegisterStatusResponseDTO verifyStatus(AccountRegisterStatusRequestDTO requestDTO) {
        AccountRegisterStatusResponseDTO responseDTO = new AccountRegisterStatusResponseDTO();
        responseDTO.setOpenAccountWay(openAccountServices.verifyAndGetOpenAccountWay(requestDTO.getOrgId(),requestDTO.getUserId(), requestDTO.getAccountRole()));
        return responseDTO;
    }

    @Override
    public OpenAccountRecordStatusEnum queryStatus(AccountRegisterStatusRequestDTO requestDTO) {
        QueryUpdateRequest request = new QueryUpdateRequest();
        request.setUserId(request.getUserId());
        request.setRole(request.getRole());
        request.setOrgId(requestDTO.getOrgId());
        return openAccountServices.get(Void.class).update(request).getRecordStatus();
    }

    /**
     * 创建个人绑卡注册开户订单, 仅适用于第一次开户
     */
    @Override
    public LanMaoGatewayRequestDTO createPersonalBindBankCardRegisterOrder(CreateRegisterOrderRequestDTO requestDTO) {
        RegisterCreateRequest request = new RegisterCreateRequest();
        request.setUserId(requestDTO.getUserId());
        request.setIdCardNo(requestDTO.getIdCardNo().toUpperCase());
        request.setBankCardNo(requestDTO.getBankCardNo());
        request.setBankCardMobileNo(requestDTO.getBankCardMobileNo());
        request.setRedirectUrl(requestDTO.getRedirectUrl());
        request.setName(requestDTO.getName());
        request.setRole(requestDTO.getAccountRole());
        request.setOpenAccountWay(requestDTO.getOpenAccountWay());
        request.setOrgId(requestDTO.getOrgId());
        LanMaoGatewayDTO lanMaoGatewayDTO = openAccountServices.get(OpenAccountOrder.class).create(request);
        LanMaoGatewayRequestDTO r = new LanMaoGatewayRequestDTO();
        r.setAction(lanMaoGatewayDTO.getAction());
        r.setParams(lanMaoGatewayDTO.getParams());
        return r;
    }

    /**
     * 更新个人注册绑卡开户记录和订单
     */
    @Override
    public UpdateRegisterOrderResponseDTO updatePersonalBindBankCardRegisterOrder(UpdateRegisterOrderRequestDTO requestDTO) {
        RegisterUpdateRequest request = new RegisterUpdateRequest();
        request.setIsBizSuccess(requestDTO.getIsBizSuccess());
        request.setRequestNo(requestDTO.getRequestNo());
        request.setAccessType(requestDTO.getAccessType());
        request.setAccountNo(requestDTO.getAccountNo());
        request.setGroupAccountNo(requestDTO.getGroupAccountNo());
        request.setAuditStatus(requestDTO.getAuditStatus());
        request.setBankCode(requestDTO.getBankCode());
        request.setErrorCode(requestDTO.getErrorCode());
        request.setErrorMessage(requestDTO.getErrorMessage());
        UpdateResponse update = openAccountServices.get(OpenAccountOrder.class).update(request);
        UpdateRegisterOrderResponseDTO responseDTO = new UpdateRegisterOrderResponseDTO();
        switch (update.getRecordStatus()) {
            case SUCCESS: {
                responseDTO.setOrderStatus(OpenAccountOrderStatusEnum.SUCCESS);
            }
            break;
            case FAILURE: {
                responseDTO.setOrderStatus(OpenAccountOrderStatusEnum.FAILURE);
            }
            break;
            default: {
                responseDTO.setOrderStatus(OpenAccountOrderStatusEnum.PROCESSING);
            }
        }
        return responseDTO;
    }

    /**
     * 创建账户激活订单, 仅适用于第一次开户
     */
    @Override
    public LanMaoGatewayRequestDTO createAccountActivateOrder(CreateRegisterOrderRequestDTO requestDTO) {
        CreateRequest request = new CreateRequest();
        request.setUserId(requestDTO.getUserId());
        request.setRedirectUrl(requestDTO.getRedirectUrl());
        request.setRole(requestDTO.getAccountRole());
        request.setOpenAccountWay(requestDTO.getOpenAccountWay());
        request.setOrgId(requestDTO.getOrgId());
        LanMaoGatewayDTO lanMaoGatewayDTO = openAccountServices.get(ActivateAccountOrder.class).create(request);
        LanMaoGatewayRequestDTO r = new LanMaoGatewayRequestDTO();
        r.setAction(lanMaoGatewayDTO.getAction());
        r.setParams(lanMaoGatewayDTO.getParams());
        return r;
    }

    /**
     * 更新激活账户订单
     */
    @Override
    public UpdateActivateAccountOrderResponseDTO updateActivateAccountOrder(UpdateActivateAccountRequestDTO requestDTO) {
        ActivateUpdateRequest request = new ActivateUpdateRequest();
        request.setAccessType(requestDTO.getAccessType());
        request.setBankCardMobileNo(requestDTO.getBankCardMobileNo());
        request.setBankCardNo(requestDTO.getBankCardNo());
        request.setBankCode(requestDTO.getBankCode());
        request.setIsBizSuccess(requestDTO.getIsBizSuccess());
        request.setRequestNo(requestDTO.getRequestNo());
        request.setAccountNo(requestDTO.getAccountNo());
        request.setGroupAccountNo(requestDTO.getGroupAccountNo());
        request.setAuditStatus(requestDTO.getAuditStatus());
        request.setName(requestDTO.getName());
        request.setIdCardNo(requestDTO.getIdCardNo().toUpperCase());
        request.setErrorCode(requestDTO.getErrorCode());
        request.setErrorMessage(requestDTO.getErrorMessage());
        UpdateResponse update = openAccountServices.get(ActivateAccountOrder.class).update(request);
        UpdateActivateAccountOrderResponseDTO updateActivateAccountOrderResponseDTO = new UpdateActivateAccountOrderResponseDTO();
        switch (update.getRecordStatus()) {
            case SUCCESS: {
                updateActivateAccountOrderResponseDTO.setOrderStatus(ActivateAccountOrderStatusEnum.SUCCESS);
            }
            break;
            case FAILURE: {
                updateActivateAccountOrderResponseDTO.setOrderStatus(ActivateAccountOrderStatusEnum.FAILURE);
            }
            break;
            case AUDIT_RETURN: {
                updateActivateAccountOrderResponseDTO.setOrderStatus(ActivateAccountOrderStatusEnum.AUDIT_RETURN);
            }
            break;
            case AUDIT_REJECT: {
                updateActivateAccountOrderResponseDTO.setOrderStatus(ActivateAccountOrderStatusEnum.AUDIT_REJECT);
            }
            break;
            case AUDITING: {
                updateActivateAccountOrderResponseDTO.setOrderStatus(ActivateAccountOrderStatusEnum.AUDITING);
            }
            break;
            default: {
                updateActivateAccountOrderResponseDTO.setOrderStatus(ActivateAccountOrderStatusEnum.PROCESSING);
            }
        }
        return updateActivateAccountOrderResponseDTO;
    }

    /**
     * 创建集团账户关联开户订单, 仅适用于第n次开户, n>1
     */
    @Override
    public LanMaoGatewayRequestDTO createGroupAccountCorrelateOrder(CreateRegisterOrderRequestDTO requestDTO) {
        CreateRequest request = new CreateRequest();
        request.setUserId(requestDTO.getUserId());
        request.setRedirectUrl(requestDTO.getRedirectUrl());
        request.setRole(requestDTO.getAccountRole());
        request.setOpenAccountWay(requestDTO.getOpenAccountWay());
        request.setOrgId(requestDTO.getOrgId());
        LanMaoGatewayDTO lanMaoGatewayDTO = openAccountServices.get(GroupAccountCorrelateOrder.class).create(request);
        LanMaoGatewayRequestDTO r = new LanMaoGatewayRequestDTO();
        r.setAction(lanMaoGatewayDTO.getAction());
        r.setParams(lanMaoGatewayDTO.getParams());
        return r;
    }

    /**
     * 更新集团账户关联订单
     */
    @Override
    public UpdateGroupRegisterOrderResponseDTO updateGroupAccountCorrelateOrder(UpdateGroupAccountCorrelateRequestDTO requestDTO) {
        UpdateRequest request = new UpdateRequest();
        request.setAccountNo(requestDTO.getAccountNo());
        request.setRequestNo(requestDTO.getRequestNo());
        request.setIsBizSuccess(requestDTO.getIsBizSuccess());
        request.setAuditStatus(AuditStatusEnum.PASSED);
        request.setErrorCode(requestDTO.getErrorCode());
        request.setErrorMessage(requestDTO.getErrorMessage());
        UpdateResponse update = openAccountServices.get(GroupAccountCorrelateOrder.class).update(request);
        UpdateGroupRegisterOrderResponseDTO updateGroupRegisterOrderResponseDTO = new UpdateGroupRegisterOrderResponseDTO();
        switch (update.getRecordStatus()) {
            case FAILURE: {
                updateGroupRegisterOrderResponseDTO.setOrderStatus(GroupAccountCorrelateOrderStatusEnum.FAILURE);
            }
            break;
            case SUCCESS: {
                updateGroupRegisterOrderResponseDTO.setOrderStatus(GroupAccountCorrelateOrderStatusEnum.SUCCESS);
            }
            break;
            default: {
                updateGroupRegisterOrderResponseDTO.setOrderStatus(GroupAccountCorrelateOrderStatusEnum.PROCESSING);
            }
            break;
        }
        return updateGroupRegisterOrderResponseDTO;
    }

    @Override
    public LanMaoGatewayRequestDTO createCompanyBindBankCardOrder(CreateCompanyRegisterOrderRequestDTO requestDTO) {
        CompanyBindBankCardExpandRequest companyBindBankCardExpandRequest = new CompanyBindBankCardExpandRequest();
        companyBindBankCardExpandRequest.setRequestNo(lanMaoSequence.getRequestNo());
        companyBindBankCardExpandRequest.setPlatformUserNo(requestDTO.getPlatformUserNo());
        companyBindBankCardExpandRequest.setBankcardNo(requestDTO.getBankcardNo());
        companyBindBankCardExpandRequest.setBankcode(BankCodeEnum.enumOf(requestDTO.getBankCode()));

        LanMaoGatewayDTO lanMaoGatewayDTO=lanMaoGatewayService.companyBindBankCardExpand(companyBindBankCardExpandRequest);
        LanMaoGatewayRequestDTO lanMaoGatewayRequestDTO=new LanMaoGatewayRequestDTO();
        lanMaoGatewayRequestDTO.setParams(lanMaoGatewayDTO.getParams());
        lanMaoGatewayRequestDTO.setAction(lanMaoGatewayDTO.getAction());

        return lanMaoGatewayRequestDTO;
    }

    @Override
    public LanMaoGatewayRequestDTO createOpenCompanyAccountOrder(OpenCompanyAccountRequestDTO openCompanyAccountRequestDTO) {
        log.info("企业存管开户预处理,机构ID={},存管请求参数={}",openCompanyAccountRequestDTO==null?null:openCompanyAccountRequestDTO.getOrgId(), JSON.toJSONString(openCompanyAccountRequestDTO));
        //1.生成存管企业绑卡注册订单,创建企业帐户;
        OpenCompanyAccountOrder openCompanyAccountOrder = accountRegisterLocalService.generateOpenCompanyAccountOrder(openCompanyAccountRequestDTO);

        //2.发起存管企业绑卡注册请求;
        CompanyBindBankCardRegisterRequest companyBindBankCardRegisterRequest=new CompanyBindBankCardRegisterRequest();
        companyBindBankCardRegisterRequest.setRequestNo(openCompanyAccountOrder.getRequestNo());
        companyBindBankCardRegisterRequest.setPlatformUserNo(openCompanyAccountOrder.getAccountNo());
        companyBindBankCardRegisterRequest.setNiiwooRedirectUrl(openCompanyAccountRequestDTO.getRedirectUrl());

        companyBindBankCardRegisterRequest.setEnterpriseName(openCompanyAccountRequestDTO.getEnterpriseName());
        companyBindBankCardRegisterRequest.setBankLicense(openCompanyAccountRequestDTO.getBankLicense());
        companyBindBankCardRegisterRequest.setOrgNo(openCompanyAccountRequestDTO.getOrgNo());
        companyBindBankCardRegisterRequest.setBusinessLicense(openCompanyAccountRequestDTO.getBusinessLicense());
        companyBindBankCardRegisterRequest.setTaxNo(openCompanyAccountRequestDTO.getTaxNo());
        companyBindBankCardRegisterRequest.setUnifiedCode(openCompanyAccountRequestDTO.getUnifiedCode());
        companyBindBankCardRegisterRequest.setCreditCode(openCompanyAccountRequestDTO.getCreditCode());
        companyBindBankCardRegisterRequest.setLegal(openCompanyAccountRequestDTO.getLegal());
        companyBindBankCardRegisterRequest.setIdCardType(CredentialsTypeEnum.enumOf(openCompanyAccountRequestDTO.getIdCardType()));
        companyBindBankCardRegisterRequest.setLegalIdCardNo(openCompanyAccountRequestDTO.getLegalIdCardNo());
        companyBindBankCardRegisterRequest.setContactPhone(openCompanyAccountRequestDTO.getContactPhone());
        companyBindBankCardRegisterRequest.setContact(openCompanyAccountRequestDTO.getContact());
        companyBindBankCardRegisterRequest.setUserRole(getCompanyUserRoleEnumByOpenWay(openCompanyAccountRequestDTO.getOpenAccountWay()));
        companyBindBankCardRegisterRequest.setBankcardNo(openCompanyAccountRequestDTO.getBankcardNo());
        companyBindBankCardRegisterRequest.setBankcode(BankCodeEnum.enumOf(openCompanyAccountRequestDTO.getBankcode()));
//        companyBindBankCardRegisterRequest.setFailTime(org.apache.commons.lang3.time.DateUtils.addYears(new Date(),10));
//        companyBindBankCardRegisterRequest.setAmount(new BigDecimal("2000000"));
        Set<String> authSet = LanMaoHelper.getAuthSetByRole(companyBindBankCardRegisterRequest.getUserRole());
        authSet.remove(UserAuthorizationEnum.RECHARGE.name());
        companyBindBankCardRegisterRequest.setAuthList(String.join(",", authSet));

        log.info("企业存管开户预处理,机构ID={},存管请求参数={}",openCompanyAccountRequestDTO==null?null:openCompanyAccountRequestDTO.getOrgId(), JSON.toJSONString(companyBindBankCardRegisterRequest));
        LanMaoGatewayDTO lanMaoGatewayDTO=lanMaoGatewayService.companyBindBankCardRegister(companyBindBankCardRegisterRequest);
        log.info("企业存管开户预处理,机构ID={},存管响应结果={}",openCompanyAccountRequestDTO==null?null:openCompanyAccountRequestDTO.getOrgId(), JSON.toJSONString(lanMaoGatewayDTO));

        LanMaoGatewayRequestDTO lanMaoGatewayRequestDTO=new LanMaoGatewayRequestDTO();
        lanMaoGatewayRequestDTO.setAction(lanMaoGatewayDTO.getAction());
        lanMaoGatewayRequestDTO.setParams(lanMaoGatewayDTO.getParams());

        return lanMaoGatewayRequestDTO;
    }

    private UserRoleEnum getCompanyUserRoleEnumByOpenWay(Byte openAccountWay){
        switch(openAccountWay){
            //1.合作机构
            case 1: return UserRoleEnum.COLLABORATOR;
            //2.担保机构
            case 2:
            //3.反担保机构
            case 3: return UserRoleEnum.GUARANTEECORP;
            //4.企业借款人
            case 4: return UserRoleEnum.BORROWERS;
            //5.企业投资人
            case 5: return UserRoleEnum.INVESTOR;
        }

        throw new BizException("ACC17028");
    }

    @Override
    public void openCompanyAccountCallback(OpenCompanyAccountCallbackReqDTO openCompanyAccountCallbackReqDTO) {
        log.info("企业绑卡注册回调,请求流水号={},请求参数={}",openCompanyAccountCallbackReqDTO.getRequestNo(), JSONObject.toJSONString(openCompanyAccountCallbackReqDTO));
        //请求处理成功
        if(openCompanyAccountCallbackReqDTO.isSuccess()){
            //审核中
            if(openCompanyAccountCallbackReqDTO.isAuditing()){
                accountRegisterLocalService.openCompanyAccountCallBackAuditIng(openCompanyAccountCallbackReqDTO);
            }
            //审核通过
            else if(openCompanyAccountCallbackReqDTO.isAuditPass()){
                accountRegisterLocalService.openCompanyAccountCallBackAuditPass(openCompanyAccountCallbackReqDTO);

                AccountCompany accountCompany = accountRegisterLocalService.getAccountCompanyFromCallBack(openCompanyAccountCallbackReqDTO);
                // 担保公司、合作机构、企业投资人，法大大签章
                if (AccountCompanyAccountTypeEnum.GUARANTEE_ORG.getType().equals(accountCompany.getAccountType()) ||
                        AccountCompanyAccountTypeEnum.COOPERATE_ORG.getType().equals(accountCompany.getAccountType()) || AccountCompanyAccountTypeEnum.INVEST_ORG.getType().equals(accountCompany.getAccountType())) {
                    userAuthorizationInfoDubboService.fadadaEnterAuth(accountCompany.getUserId());
                }
            }
            //审核退回
            else if(openCompanyAccountCallbackReqDTO.isAuditBack()){
                accountRegisterLocalService.openCompanyAccountCallBackAuditBack(openCompanyAccountCallbackReqDTO);
            }
            //审核拒绝
            else if(openCompanyAccountCallbackReqDTO.isAuditRefused()){
                accountRegisterLocalService.openCompanyAccountCallBackAuditRefuse(openCompanyAccountCallbackReqDTO);
            }
        }
        //请求处理失败
        else{
            accountRegisterLocalService.openCompanyAccountCallBackError(openCompanyAccountCallbackReqDTO);
        }
    }

    @Override
    public UpdateEnterpriseAccountResponseDTO updateMockEnterpriseOrder(UpdateEnterpriseAccountRequestDTO updateRequestDto) {
        UpdateEnterpriseAccountResponseDTO responseDTO = new UpdateEnterpriseAccountResponseDTO();
        EnterpriseRegisterUpdateRequest mockEnterpriseRegisterUpdateRequest = new EnterpriseRegisterUpdateRequest();
        mockEnterpriseRegisterUpdateRequest.setIsBizSuccess(updateRequestDto.getIsBizSuccess());
        mockEnterpriseRegisterUpdateRequest.setBankCardNo(updateRequestDto.getBankcardNo());
        mockEnterpriseRegisterUpdateRequest.setBankCode(updateRequestDto.getBankCode().getCode());
        mockEnterpriseRegisterUpdateRequest.setAccountNo(updateRequestDto.getAccountNo());
        mockEnterpriseRegisterUpdateRequest.setAuditStatus(updateRequestDto.getAuditStatus());
        mockEnterpriseRegisterUpdateRequest.setRequestNo(updateRequestDto.getRequestNo());
        mockEnterpriseRegisterUpdateRequest.setErrorMessage(updateRequestDto.getErrorMessage());
        mockEnterpriseRegisterUpdateRequest.setErrorCode(updateRequestDto.getErrorCode());
        responseDTO.setOrderStatus(openAccountServices.get(EnterpriseRegisterOrder.class).update(mockEnterpriseRegisterUpdateRequest).getRecordStatus());
        return responseDTO;
    }


}
